﻿Imports Windows.Storage.Streams

Public Class MemoryRandomAccessStream
    Implements IRandomAccessStream

    Private m_InternalStream As Stream

    Public Sub New(stream As Stream)
        Me.m_InternalStream = stream
    End Sub

    Public Sub New(bytes() As Byte)
        Me.m_InternalStream = New MemoryStream(bytes)
    End Sub

    Public Function ReadAsync(buffer As IBuffer, count As UInteger, options As InputStreamOptions) As IAsyncOperationWithProgress(Of IBuffer, UInteger) Implements IInputStream.ReadAsync
        Dim inputStream = Me.GetInputStreamAt(0)
        Return inputStream.ReadAsync(buffer, count, options)
    End Function

    Public Function FlushAsync() As IAsyncOperation(Of Boolean) Implements IOutputStream.FlushAsync
        Dim outputStream = Me.GetOutputStreamAt(0)
        Return outputStream.FlushAsync()
    End Function

    Public Function WriteAsync(buffer As IBuffer) As IAsyncOperationWithProgress(Of UInteger, UInteger) Implements IOutputStream.WriteAsync
        Dim outputStream = Me.GetOutputStreamAt(0)
        Return outputStream.WriteAsync(buffer)
    End Function

    Public ReadOnly Property CanRead As Boolean Implements IRandomAccessStream.CanRead
        Get
            Return True
        End Get
    End Property

    Public ReadOnly Property CanWrite As Boolean Implements IRandomAccessStream.CanWrite
        Get
            Return True
        End Get
    End Property

    Public Function CloneStream() As IRandomAccessStream Implements IRandomAccessStream.CloneStream
        Throw New NotSupportedException()
    End Function

    Public Function GetInputStreamAt(position As ULong) As IInputStream Implements IRandomAccessStream.GetInputStreamAt
        Me.m_InternalStream.Seek(CType(position, Long), SeekOrigin.Begin)

        Return Me.m_InternalStream.AsInputStream()
    End Function

    Public Function GetOutputStreamAt(position As ULong) As IOutputStream Implements IRandomAccessStream.GetOutputStreamAt
        Me.m_InternalStream.Seek(CType(position, Long), SeekOrigin.Begin)
        Return Me.m_InternalStream.AsOutputStream()
    End Function

    Public ReadOnly Property Position As ULong Implements IRandomAccessStream.Position
        Get
            Return Me.m_InternalStream.Position
        End Get
    End Property

    Public Sub Seek(position As ULong) Implements IRandomAccessStream.Seek
        Me.m_InternalStream.Seek(CType(position, ULong), 0)
    End Sub

    Public Property Size As ULong Implements IRandomAccessStream.Size
        Get
            Return CType(Me.m_InternalStream.Length, ULong)
        End Get
        Set(value As ULong)
            Me.m_InternalStream.SetLength(CType(value, ULong))
        End Set
    End Property

#Region "IDisposable Support"
    Private disposedValue As Boolean ' Per rilevare chiamate ridondanti

    ' IDisposable
    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                Me.m_InternalStream.Dispose()
            End If

            ' TODO: liberare risorse non gestite (oggetti non gestiti) ed eseguire l'override del seguente Finalize().
            ' TODO: impostare campi di grandi dimensioni su null.
        End If
        Me.disposedValue = True
    End Sub

    ' TODO: eseguire l'override di Finalize() solo se Dispose(ByVal disposing As Boolean) dispone del codice per liberare risorse non gestite.
    'Protected Overrides Sub Finalize()
    '    ' Non modificare questo codice. Inserire il codice di pulizia in Dispose(ByVal disposing As Boolean).
    '    Dispose(False)
    '    MyBase.Finalize()
    'End Sub

    ' Questo codice è aggiunto da Visual Basic per implementare in modo corretto il modello Disposable.
    Public Sub Dispose() Implements IDisposable.Dispose
        ' Non modificare questo codice. Inserire il codice di pulizia in Dispose(disposing As Boolean).
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub

#End Region

End Class
